X-Forwarded-For with Istio, Kubernetes and GCP load balancer
DevOpsIstioKubernetesWhat I want: X-Forwarded-For HTTP Header in a Laravel application. In other words, the remote IP of the client.
What is my setup.
- Kubernetes
- Istio, Istio-ingressgateway
- GCP Load Balancer (External Network Load balancer, not a Regional external HTTP(S)).
I had some trouble to find the correct information, here is a quick post to say it works for me, here how.
I have seen two main solution, the second works for me.
xff_num_trusted_hops #
based on a blog post by Blablacar on medium
The idea is to trust hops before by changing the configuration of Envoy with the following.
I hopped that with the use_remote_address: true
would help me, but it wasn't enought in my case.
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: ingressgateway-settings
namespace: istio-system
spec:
configPatches:
- applyTo: NETWORK_FILTER
match:
context: GATEWAY
listener:
filterChain:
filter:
name: envoy.http_connection_manager
patch:
operation: MERGE
value:
typed_config:
"@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager"
use_remote_address: true
xff_num_trusted_hops: 2
workloadSelector:
labels:
istio: ingressgateway
It did changes the IP from the X-Forwarded-For header, but only from a local perspective. It did not get me the Client IP.
I found some alternative to this idea.
Here is a configuration of the Gateway Topology.
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
meshConfig:
defaultConfig:
gatewayTopology:
numTrustedProxies: 2
ExternalTrafficPolicy #
The solution was found on istio documentation (the Network Loadbalancer tab)
What works for me was to set the externalTrafficPolicy
to Local
in the Istio Ingress Gateway.
kubectl patch svc istio-ingressgateway -n istio-system -p '{"spec":{"externalTrafficPolicy":"Local"}}'
Once this patch, I did get the correct Client IP.